home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / FPU-EMU / REG_U_MU.S < prev    next >
Text File  |  1994-05-27  |  4KB  |  164 lines

  1.     .file    "reg_u_mul.S"
  2. /*---------------------------------------------------------------------------+
  3.  |  reg_u_mul.S                                                              |
  4.  |                                                                           |
  5.  | Core multiplication routine                                               |
  6.  |                                                                           |
  7.  | Copyright (C) 1992,1993                                                   |
  8.  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  9.  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
  10.  |                                                                           |
  11.  |                                                                           |
  12.  +---------------------------------------------------------------------------*/
  13.  
  14. /*---------------------------------------------------------------------------+
  15.  |   Basic multiplication routine.                                           |
  16.  |   Does not check the resulting exponent for overflow/underflow            |
  17.  |                                                                           |
  18.  |   reg_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw);         |
  19.  |                                                                           |
  20.  |   Internal working is at approx 128 bits.                                 |
  21.  |   Result is rounded to nearest 53 or 64 bits, using "nearest or even".    |
  22.  +---------------------------------------------------------------------------*/
  23.  
  24. #include "exception.h"
  25. #include "fpu_asm.h"
  26. #include "control_w.h"
  27.  
  28.  
  29.  
  30. #ifdef REENTRANT_FPU
  31. /*  Local storage on the stack: */
  32. #define FPU_accum_0    -4(%ebp)    /* ms word */
  33. #define FPU_accum_1    -8(%ebp)
  34.  
  35. #else
  36. /*  Local storage in a static area: */
  37. .data
  38.     .align 4,0
  39. FPU_accum_0:
  40.     .long    0
  41. FPU_accum_1:
  42.     .long    0
  43. #endif REENTRANT_FPU
  44.  
  45.  
  46. .text
  47.     .align 2,144
  48.  
  49. .globl _reg_u_mul
  50. _reg_u_mul:
  51.     pushl    %ebp
  52.     movl    %esp,%ebp
  53. #ifdef REENTRANT_FPU
  54.     subl    $8,%esp
  55. #endif REENTRANT_FPU
  56.  
  57.     pushl    %esi
  58.     pushl    %edi
  59.     pushl    %ebx
  60.  
  61.     movl    PARAM1,%esi
  62.     movl    PARAM2,%edi
  63.  
  64. #ifdef PARANOID
  65.     testl    $0x80000000,SIGH(%esi)
  66.     jz    L_bugged
  67.     testl    $0x80000000,SIGH(%edi)
  68.     jz    L_bugged
  69. #endif PARANOID
  70.  
  71. #ifdef DENORM_OPERAND
  72.     movl    EXP(%esi),%eax
  73.     cmpl    EXP_UNDER,%eax
  74.     jg    xOp1_not_denorm
  75.  
  76.     call    _denormal_operand
  77.     orl    %eax,%eax
  78.     jnz    fpu_Arith_exit
  79.  
  80. xOp1_not_denorm:
  81.     movl    EXP(%edi),%eax
  82.     cmpl    EXP_UNDER,%eax
  83.     jg    xOp2_not_denorm
  84.  
  85.     call    _denormal_operand
  86.     orl    %eax,%eax
  87.     jnz    fpu_Arith_exit
  88.  
  89. xOp2_not_denorm:
  90. #endif DENORM_OPERAND
  91.  
  92.     xorl    %ecx,%ecx
  93.     xorl    %ebx,%ebx
  94.  
  95.     movl    SIGL(%esi),%eax
  96.     mull    SIGL(%edi)
  97.     movl    %eax,FPU_accum_0
  98.     movl    %edx,FPU_accum_1
  99.  
  100.     movl    SIGL(%esi),%eax
  101.     mull    SIGH(%edi)
  102.     addl    %eax,FPU_accum_1
  103.     adcl    %edx,%ebx
  104. /*    adcl    $0,%ecx        // overflow here is not possible */
  105.  
  106.     movl    SIGH(%esi),%eax
  107.     mull    SIGL(%edi)
  108.     addl    %eax,FPU_accum_1
  109.     adcl    %edx,%ebx
  110.     adcl    $0,%ecx
  111.  
  112.     movl    SIGH(%esi),%eax
  113.     mull    SIGH(%edi)
  114.     addl    %eax,%ebx
  115.     adcl    %edx,%ecx
  116.  
  117.     movl    EXP(%esi),%eax    /* Compute the exponent */
  118.     addl    EXP(%edi),%eax
  119.     subl    EXP_BIAS-1,%eax
  120.  
  121. /*  Have now finished with the sources */
  122.     movl    PARAM3,%edi    /* Point to the destination */
  123.     movl    %eax,EXP(%edi)
  124.  
  125. /*  Now make sure that the result is normalized */
  126.     testl    $0x80000000,%ecx
  127.     jnz    LResult_Normalised
  128.  
  129.     /* Normalize by shifting left one bit */
  130.     shll    $1,FPU_accum_0
  131.     rcll    $1,FPU_accum_1
  132.     rcll    $1,%ebx
  133.     rcll    $1,%ecx
  134.     decl    EXP(%edi)
  135.  
  136. LResult_Normalised:
  137.     movl    FPU_accum_0,%eax
  138.     movl    FPU_accum_1,%edx
  139.     orl    %eax,%eax
  140.     jz    L_extent_zero
  141.  
  142.     orl    $1,%edx
  143.  
  144. L_extent_zero:
  145.     movl    %ecx,%eax
  146.     jmp    fpu_reg_round
  147.  
  148.  
  149. #ifdef PARANOID
  150. L_bugged:
  151.     pushl    EX_INTERNAL|0x205
  152.     call    EXCEPTION
  153.     pop    %ebx
  154.     jmp    L_exit
  155.  
  156. L_exit:
  157.     popl    %ebx
  158.     popl    %edi
  159.     popl    %esi
  160.     leave
  161.     ret
  162. #endif PARANOID
  163.  
  164.